home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
CH_4.4
/
XPM
/
XPM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
7KB
|
308 lines
/*
* xpm.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/*
* XP(olygon)M(oments)
*
* extracts global features and performs a moment analysis
* on planar boundaries
*
*/
#include "xpm.h"
#define WINDOW_ROWS 3
#define NDIRECTIONS 8
#define THRESH 1
#define MIN_POLY_SIZE 20
#define ZERO 0
#define ROOT2 1.414213562
#define NA_MAX 128 /* lim of points, see ph.c */
#define ON 1
#define OFF 0
#define RESET ON
#define NO_RESET OFF
#undef DEBUG
#undef SHOW_CURV_PT
/* global variables */
extern short tiffInput; /* flag=0 if no ImageIn to set tags; else =1 */
struct curv_points *curv_head_in[NDIRECTIONS];
struct curv_points *curv_head_out[NDIRECTIONS];
struct curv_points *curv_tail_in[NDIRECTIONS];
struct curv_points *curv_tail_out[NDIRECTIONS];
struct polygon *poly_head_ptr;
struct polygon *poly_tail_ptr;
float *delta_phik, *delta_lk;
long ncp = 0;
int loop_switch = ON; /* enable/disable loop for polyg. approx */
int hull_switch = ON; /* enable/disable eval of convex hull */
int n_ap_max = NA_MAX; /* max no allowed vertices in approx. poly */
extern char *optarg;
extern int optind, opterr;
extern short tiffInput; /* flag=0 if no ImageIn to set tags; else =1 */
/*
* usage of routine
*/
void
usage (char *progname)
{
progname = last_bs (progname);
printf ("USAGE: %s inimg outimg [-L]\n", progname);
printf ("\n%s extracts global features and performs a moment analysis\n", progname);
printf ("on planar boundaries\n\n");
printf ("ARGUMENTS:\n");
printf (" inimg: input image filename (TIF)\n");
printf (" outimg: output image filename (TIF)\n\n");
printf ("OPTIONS:\n");
printf (" -L: print Software License for this module\n");
exit (1);
}
void
init_structs ()
{
int m;
for (m = 0; m < NDIRECTIONS; m++) {
curv_tail_in[m] = curv_tail_out[m] = NULL;
curv_head_in[m] = curv_head_out[m] = NULL;
}
poly_head_ptr = NULL;
poly_tail_ptr = NULL;
}
/*
* acquire first three rows from input image
* and transfer them to the window
*/
void
xfer_first_3_rows (unsigned char *window[], Image * imgIO)
{
int ir;
for (ir = 0; ir < 3; ir++)
getrow (*(window + ir), ir, imgIO);
}
/*
* acquire next from input image
* and transfer it to the window
*/
void
xfer_next_row (unsigned char *window[], int ir, Image * imgIO)
{
int y;
unsigned char *char_ptr;
char_ptr = *(window + (ir % WINDOW_ROWS));
y = ir + 3; /* offset of 3 from first_3_rows */
getrow (char_ptr, y, imgIO);
}
/*
* zero border error message
*/
void
border_err (int row, int col)
{
printf ("...AOI border not zeroed at row %d, col %d\n", row, col);
exit (1);
}
/*
* image border must be zeroed -- check it!
*/
void
check_border (unsigned char *window[], int ir, int jmax, int imax, Image * imgIO)
{
int jc;
unsigned char *char_ptr;
if (ir == 0) {
char_ptr = *(window + (ir % WINDOW_ROWS));
for (jc = 0; jc < jmax; jc++)
if (*(char_ptr + jc) != ZERO)
border_err (ir, jc);
}
if (ir == (imax - WINDOW_ROWS)) {
char_ptr = *(window + ((ir + 0) % WINDOW_ROWS));
if (*(char_ptr) != ZERO)
border_err (ir, 0);
if (*(char_ptr + (jmax - 1)) != ZERO)
border_err (ir, jmax - 1);
char_ptr = *(window + ((ir + 1) % WINDOW_ROWS));
if (*(char_ptr) != ZERO)
border_err (ir + 1, 0);
if (*(char_ptr + (jmax - 1)) != ZERO)
border_err (ir + 1, jmax - 1);
char_ptr = *(window + ((ir + 2) % WINDOW_ROWS));
for (jc = 0; jc < jmax; jc++)
if (*(char_ptr + jc) != ZERO)
border_err (ir + 2, jc);
}
else {
char_ptr = *(window + (ir % WINDOW_ROWS));
if (*(char_ptr) != ZERO)
border_err (ir, 0);
if (*(char_ptr + (jmax - 1)) != ZERO)
border_err (ir, jmax - 1);
}
}
/*
* memory allocation for image (one row at a time)
*/
int
img_alloc (unsigned char *img[], int nr, int nc)
{
int ir;
for (ir = 0; ir < nr; ir++) {
if ((*(img + ir) = (unsigned char *) calloc (nc, sizeof (unsigned char))) == NULL)
return (0);
else
*(img + ir) += 0;
}
return (1);
}
void
main (int argc, char *argv[])
{
unsigned char *window[WINDOW_ROWS];
int ir;
int nr, nc;
int jmin, imin, jmax, imax;
int left_x, right_x;
float *delta_phikp, *delta_lkp;
Image *imgIn; /* input image */
Image *imgOut; /* output image */
int i_arg;
/*
* cmd line options
*/
static char *optstring = "c:bL";
/*
* parse command line
*/
optind = 3; /* set getopt to point to the 3rd arg */
opterr = ON; /* give error messages */
if (argc < 3)
usage (argv[0]);
while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
switch (i_arg) {
case 'L':
print_sos_lic ();
exit (0);
default:
printf ("\ngetopt: unknown condition encountered\n");
exit (1);
break;
}
}
/*
* initialize structures
*/
init_structs ();
/*
* get the input image
*/
imgIn = ImageIn (argv[1]);
if (imgIn->bps == 8 && imgIn->spp == 3) {
printf ("Got RGB image!!!\n");
fprintf (stderr, "Can only work with Grayscale or Binary TIFF files!!!\n");
exit (1);
}
/* reset tiffInput so that we write a grayscale file (i.e tags are not copied) */
tiffInput = 0;
/*
* initialize for output image (Grayscale!!)
*/
imgOut = ImageAlloc (imgIn->height, imgIn->width, 8);
jmin = imin = 0;
jmax = imgIn->width;
imax = imgIn->height;
left_x = jmin;
right_x = jmax - 1;
nc = jmax - jmin;
nr = imax - imin;
#ifdef DEBUG
printf ("\n...nc = %d, nr = %d\n", nc, nr);
#endif
/*
* zero outer border of image
*/
zero_border (imgIn, 2);
/*
* allocate memory
*/
if ((img_alloc (window, WINDOW_ROWS, nc) == 0))
exitmess ("window", 1);
printf ("\n...scan image...\n");
xfer_first_3_rows (window, imgIn);
for (ir = 0; ir < imax - WINDOW_ROWS; ir++) {
check_border (window, ir, jmax, imax, imgIn);
curvature_points (window, ir, jmax, imax);
xfer_next_row (window, ir, imgIn);
}
check_border (window, ir, jmax, imax, imgIn);
curvature_points (window, ir, jmax, imax);
if ((delta_phikp = (float *) calloc (ncp, sizeof (float))) == NULL)
exitmess ("delta_phik", 1);
if ((delta_lkp = (float *) calloc (ncp, sizeof (float))) == NULL)
exitmess ("delta_phik", 1);
delta_phik = delta_phikp;
delta_lk = delta_lkp;
/*
* construct lists representing individual boundaries
*/
printf ("...construct linked lists of boundary points...\n");
linkage (imgIn, imgOut, WHITE);
free (delta_phikp);
free (delta_lkp);
printf ("\n...writing graphics output file %s\n", argv[2]);
ImageOut (argv[2], imgOut);
}